﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Media;

namespace ChineseCheselrm1
{
    /// <summary>
    /// 游戏类
    /// </summary>
    class Game
    {
        //定义游戏高度
        private const int GameHeight = 1100;
        //定义游戏宽度
        private const int GameWidth = 1000;
        //定义列数
        private const int Cols = 9;
        //定义行数
        private const int Rows = 10;

        /// <summary>
        /// 正在走棋的一方
        /// </summary>
        public Gameside ThisSide { get; set; }

        /// <summary>
        /// 定义委托
        /// </summary>
        public delegate void GameChanged();

        /// <summary>
        /// 定义事件
        /// </summary>
        public event GameChanged gameChanged;

        /// <summary>
        /// 鼠标点击时的原来位置坐标
        /// </summary>
        private Point OldLocation { get; set; }

        /// <summary>
        ///所有块类的集合
        /// </summary>
        public List<Block> Blocks { get; set; }

        /// <summary>
        /// 定义当前鼠标所在的block
        /// </summary>
        private Block MouseBlock { get; set; }

        /// <summary>
        /// 点击鼠标时的block
        /// </summary>
        private Block BlockNow { get; set; }

        /// <summary>
        /// 目标棋子的block
        /// </summary>
        private Block BlockSelect { get; set; }

        /// <summary>
        /// messagebox里的字符串
        /// </summary>
        public string MessageStr { get; set; }

        /// <summary>
        /// 移动合法
        /// </summary>
        public bool Flag { get; set; }

        /// <summary>
        /// 时间间隔
        /// </summary>
        public DateTime NextTime { get; set; }

        /// <summary>
        /// 初始化
        /// </summary>
        public Game()
        {
            //初始化messagebox
            MessageStr = "落子错误！";
            //初始化当前游戏方
            ThisSide = Gameside.红;
            //初始化block
            Blocks = new List<Block>();
            for (int i = 0; i < Rows; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    Blocks.Add(new Block(Gameside.红, Blockstatus.空, 
                        new Rectangle(50 + j * 100, 50 + i * 100, 100, 100), 
                        new Point(i, j)));
                }
            }
            //时间间隔
            NextTime = System.DateTime.Now.AddSeconds(90);
            //更改每个block的两个属性
            Blocks[0].Status = Blockstatus.车; Blocks[0].Side = Gameside.黑;
            Blocks[1].Status = Blockstatus.马; Blocks[1].Side = Gameside.黑;
            Blocks[2].Status = Blockstatus.象; Blocks[2].Side = Gameside.黑;
            Blocks[3].Status = Blockstatus.士; Blocks[3].Side = Gameside.黑;
            Blocks[4].Status = Blockstatus.帅; Blocks[4].Side = Gameside.黑;
            Blocks[5].Status = Blockstatus.士; Blocks[5].Side = Gameside.黑;
            Blocks[6].Status = Blockstatus.象; Blocks[6].Side = Gameside.黑;
            Blocks[7].Status = Blockstatus.马; Blocks[7].Side = Gameside.黑;
            Blocks[8].Status = Blockstatus.车; Blocks[8].Side = Gameside.黑;
            Blocks[19].Status = Blockstatus.炮; Blocks[19].Side = Gameside.黑;
            Blocks[25].Status = Blockstatus.炮; Blocks[25].Side = Gameside.黑;
            Blocks[27].Status = Blockstatus.兵; Blocks[27].Side = Gameside.黑;
            Blocks[29].Status = Blockstatus.兵; Blocks[29].Side = Gameside.黑;
            Blocks[31].Status = Blockstatus.兵; Blocks[31].Side = Gameside.黑;
            Blocks[33].Status = Blockstatus.兵; Blocks[33].Side = Gameside.黑;
            Blocks[35].Status = Blockstatus.兵; Blocks[35].Side = Gameside.黑;
            Blocks[54].Status = Blockstatus.兵; Blocks[54].Side = Gameside.红;
            Blocks[56].Status = Blockstatus.兵; Blocks[56].Side = Gameside.红;
            Blocks[58].Status = Blockstatus.兵; Blocks[58].Side = Gameside.红;
            Blocks[60].Status = Blockstatus.兵; Blocks[60].Side = Gameside.红;
            Blocks[62].Status = Blockstatus.兵; Blocks[62].Side = Gameside.红;
            Blocks[64].Status = Blockstatus.炮; Blocks[64].Side = Gameside.红;
            Blocks[70].Status = Blockstatus.炮; Blocks[70].Side = Gameside.红;
            Blocks[81].Status = Blockstatus.车; Blocks[81].Side = Gameside.红;
            Blocks[82].Status = Blockstatus.马; Blocks[82].Side = Gameside.红;
            Blocks[83].Status = Blockstatus.象; Blocks[83].Side = Gameside.红;
            Blocks[84].Status = Blockstatus.士; Blocks[84].Side = Gameside.红;
            Blocks[85].Status = Blockstatus.帅; Blocks[85].Side = Gameside.红;
            Blocks[86].Status = Blockstatus.士; Blocks[86].Side = Gameside.红;
            Blocks[87].Status = Blockstatus.象; Blocks[87].Side = Gameside.红;
            Blocks[88].Status = Blockstatus.马; Blocks[88].Side = Gameside.红;
            Blocks[89].Status = Blockstatus.车; Blocks[89].Side = Gameside.红;
        }

        /// <summary>
        /// 画当前游戏场景
        /// </summary>
        /// <param name="g">绘图句柄</param>
        /// <param name="size">绘图区域大小</param>
        public void Draw(Graphics g, Size size)
        {
            //使用二次绘图
            Image img = new Bitmap(GameWidth, GameHeight);
            Graphics _g = Graphics.FromImage(img);
            //定义棋盘单元格高度和宽度
            int unitColWidths = 100;
            int unitRowHeights = 100;
            Rectangle rec = new Rectangle(new Point(0, 0), new Size(GameWidth, GameHeight));
            _g.DrawImage(Properties.Resources.backgrand, rec);
            //定义画笔
            Pen thinpen = new Pen(Color.Black, 2);
            Pen thickpen = new Pen(Color.Black, 6);
            //棋盘边框
            _g.DrawRectangle(thickpen, unitColWidths - 10, unitRowHeights - 10, unitColWidths * 8 + 20, unitRowHeights * 9 + 20);
            //横线
            for (int i = 0; i < Rows; i++)
            {
                PointF pointstart = new PointF(unitColWidths, (i + 1) * unitRowHeights);
                PointF pointEnd = new PointF(unitColWidths * Cols, (i + 1) * unitRowHeights);
                _g.DrawLine(thinpen, pointstart, pointEnd);
            }
            //竖线 
            //左侧边缘
            PointF pointstart1 = new PointF(unitColWidths, unitRowHeights);
            PointF pointend1 = new PointF(unitColWidths, unitRowHeights * 10);
            _g.DrawLine(thinpen, pointstart1, pointend1);
            //右侧边缘
            PointF pointstart2 = new PointF(unitColWidths * 9, unitRowHeights);
            PointF pointend2 = new PointF(unitColWidths * 9, unitRowHeights * 10);
            _g.DrawLine(thinpen, pointstart2, pointend2);
            //上侧竖线
            for (int i = 1; i < Cols - 1; i++)
            {
                PointF pointstart = new PointF((i + 1) * unitColWidths, unitRowHeights);
                PointF pointEnd = new PointF((i + 1) * unitColWidths, unitRowHeights * 5);
                _g.DrawLine(thinpen, pointstart, pointEnd);
            }
            //下侧竖线
            for (int i = 1; i < Cols - 1; i++)
            {
                PointF pointstart = new PointF((i + 1) * unitColWidths, unitRowHeights * 6);
                PointF pointEnd = new PointF((i + 1) * unitColWidths, unitRowHeights * 10);
                _g.DrawLine(thinpen, pointstart, pointEnd);
            }
            //九宫格交叉线
            _g.DrawLine(thinpen, new Point(unitColWidths * 4, unitRowHeights), new Point(unitColWidths * 6, unitRowHeights * 3));
            _g.DrawLine(thinpen, new Point(unitColWidths * 6, unitRowHeights), new Point(unitColWidths * 4, unitRowHeights * 3));
            _g.DrawLine(thinpen, new Point(unitColWidths * 4, unitRowHeights * 8), new Point(unitColWidths * 6, unitRowHeights * 10));
            _g.DrawLine(thinpen, new Point(unitColWidths * 6, unitRowHeights * 8), new Point(unitColWidths * 4, unitRowHeights * 10));
            //书写“楚河汉界”
            Font font1 = new Font("楷体", (float)(unitRowHeights * 0.8), FontStyle.Regular, GraphicsUnit.Pixel);
            SolidBrush fontBrush = new SolidBrush(Color.Black);
            _g.DrawString("楚 河", font1, fontBrush, new Point(2 * unitColWidths, (int)(unitRowHeights * 5.1)));
            _g.DrawString("漢 界", font1, fontBrush, new Point(6 * unitColWidths, (int)(unitRowHeights * 5.1)));
            //绘制棋盘炮台兵站
            DrawPaotai(_g, new Point(2 * unitColWidths, 3 * unitRowHeights));
            DrawPaotai(_g, new Point(8 * unitColWidths, 3 * unitRowHeights));
            DrawPaotai(_g, new Point(2 * unitColWidths, 8 * unitRowHeights));
            DrawPaotai(_g, new Point(8 * unitColWidths, 8 * unitRowHeights));
            DrawPaotai(_g, new Point(3 * unitColWidths, 4 * unitRowHeights));
            DrawPaotai(_g, new Point(5 * unitColWidths, 4 * unitRowHeights));
            DrawPaotai(_g, new Point(7 * unitColWidths, 4 * unitRowHeights));
            DrawPaotai(_g, new Point(3 * unitColWidths, 7 * unitRowHeights));
            DrawPaotai(_g, new Point(5 * unitColWidths, 7 * unitRowHeights));
            DrawPaotai(_g, new Point(7 * unitColWidths, 7 * unitRowHeights));
            DrawBianbing1(_g, new Point(9 * unitColWidths, 4 * unitRowHeights));
            DrawBianbing1(_g, new Point(9 * unitColWidths, 7 * unitRowHeights));
            DrawBianbing2(_g, new Point(1 * unitColWidths, 4 * unitRowHeights));
            DrawBianbing2(_g, new Point(1 * unitColWidths, 7 * unitRowHeights));
            //画棋子
            foreach (var block in Blocks)
            {
                block.Draw(_g);
            }
            //重画MouseBlock的图使得黑子吃红子时黑子在上
            if (MouseBlock != null)
            {
                MouseBlock.Draw(_g);
            }
            //将画出来的图粘在画图区域
            g.DrawImage(img, new Rectangle(new Point(0, 0), size));
        }

        /// <summary>
        /// 绘制棋盘中间的兵站和炮台
        /// </summary>
        /// <param name="g">绘图句柄</param>
        /// <param name="point">矩阵坐标</param>
        public void DrawPaotai(Graphics g, Point point)
        {
            int x = point.X;
            int y = point.Y;
            Pen pen = new Pen(Color.Black);
            g.DrawLine(pen, x - 30, y - 10, x - 10, y - 10);
            g.DrawLine(pen, x - 10, y - 30, x - 10, y - 10);
            g.DrawLine(pen, x + 30, y + 10, x + 10, y + 10);
            g.DrawLine(pen, x + 10, y + 30, x + 10, y + 10);
            g.DrawLine(pen, x + 30, y - 10, x + 10, y - 10);
            g.DrawLine(pen, x + 10, y - 30, x + 10, y - 10);
            g.DrawLine(pen, x - 30, y + 10, x - 10, y + 10);
            g.DrawLine(pen, x - 10, y + 30, x - 10, y + 10);
        }

        /// <summary>
        /// 绘制左侧边上的兵站
        /// </summary>
        /// <param name="g">绘图句柄</param>
        /// <param name="point">游戏区域大小</param>
        private void DrawBianbing1(Graphics g, Point point)
        {
            int x = point.X;
            int y = point.Y;
            Pen pen = new Pen(Color.Black);
            g.DrawLine(pen, x - 30, y - 10, x - 10, y - 10);
            g.DrawLine(pen, x - 10, y - 30, x - 10, y - 10);
            g.DrawLine(pen, x - 30, y + 10, x - 10, y + 10);
            g.DrawLine(pen, x - 10, y + 30, x - 10, y + 10);
        }

        /// <summary>
        /// 绘制右侧边上的兵站
        /// </summary>
        /// <param name="g">绘图句柄</param>
        /// <param name="point">矩阵坐标</param>
        private void DrawBianbing2(Graphics g, Point point)
        {
            int x = point.X;
            int y = point.Y;
            Pen pen = new Pen(Color.Black);
            g.DrawLine(pen, x + 30, y + 10, x + 10, y + 10);
            g.DrawLine(pen, x + 10, y + 30, x + 10, y + 10);
            g.DrawLine(pen, x + 30, y - 10, x + 10, y - 10);
            g.DrawLine(pen, x + 10, y - 30, x + 10, y - 10);
        }

        /// <summary>
        /// 处理鼠标点击事件
        /// </summary>
        /// <param name="point">矩阵坐标</param>
        public void MouseDown(Point point, Size size)
        {
            //坐标吻合
            int newX = point.X * GameWidth / size.Width;
            int newY = point.Y * GameHeight / size.Height;
            point = new Point(point.X * GameWidth / size.Width, point.Y * GameHeight / size.Height);
            //鼠标点击过后上一个绿色边框取消,但是第一步之前没有绿色边框
            BlockNow = Blocks.FirstOrDefault(m => m.Rec.Contains(point));
            if (BlockSelect != null)
            {
                //点击的地方不为空，之前的绿框消失
                BlockSelect.UpSelect = false;
            }
            if (BlockNow != null && BlockNow.Status != Blockstatus.空 && BlockNow.Side == ThisSide)
            {
                //当前点击的这个点point在contains里面，并且这个block不为空
                MouseBlock = BlockNow;
                OldLocation = BlockNow.Rec.Location;
                //鼠标点击的这个点出现红色的边框
                BlockNow.IsSelect = true;
                //播放点击棋子的音乐
                SoundPlayer player = new SoundPlayer(Properties.Resources.点击棋子);
                player.Play();
            }
            else
            {
                return;
            }
        }

        /// <summary>
        /// 处理鼠标移动事件
        /// </summary>
        /// <param name="point">矩阵坐标</param>
        /// <param name="size"> 游戏区域大小</param>
        public void MouseMove(Point point, Size size)
        {
            //坐标吻合
            int newX = point.X * GameWidth / size.Width;
            int newY = point.Y * GameHeight / size.Height;
            //mouseblock不能为空
            if (MouseBlock == null) return;
            else
            {
                MouseBlock.Rec = new Rectangle(newX - MouseBlock.Rec.Width / 2, newY - MouseBlock.Rec.Height / 2,
                MouseBlock.Rec.Width, MouseBlock.Rec.Height);
            }
            gameChanged?.Invoke();
        }

        /// <summary>
        /// 处理鼠标离开事件
        /// </summary>
        /// <param name="point">矩阵坐标</param>
        /// <param name="size">游戏区域大小</param>
        public void MouseUp(Point point, Size size)
        {
            //坐标吻合
            int newX = point.X * GameWidth / size.Width;
            int newY = point.Y * GameHeight / size.Height;
            if (MouseBlock == null) return;
            //当前鼠标的block不能为空
            else
            {
                //目标block也不能为空，为空则返回原位
                MouseBlock.Rec = new Rectangle(OldLocation.X, OldLocation.Y, MouseBlock.Rec.Width, MouseBlock.Rec.Height);
                //释放鼠标则红色正方形取消
                MouseBlock.IsSelect = false;
                //先假设移动合法
                Flag = true;
                //newX ，newY是新的位置，oldLocation是旧位置，需要判断移动是否合法，如果合法，将原block置空，将新block置为原棋子
                BlockSelect = Blocks.FirstOrDefault(m => m.Rec.Contains(new Point(newX, newY)));
                //取起始点和目标点的矩阵坐标
                if (BlockSelect == null) return;
                Point pointSource = MouseBlock.Point;
                Point pointDestination = BlockSelect.Point;
                //定义移动的坐标
                int _X = pointDestination.X - pointSource.X;
                int _Y = pointDestination.Y - pointSource.Y;
                if (BlockSelect != null && MouseBlock.Status != Blockstatus.空 && (BlockSelect.Status == Blockstatus.空 || BlockSelect.Side != MouseBlock.Side))
                {
                    //注意两个老王不能打照面，先找到黑将的block所在位置
                    var heijiangNow = Blocks.FirstOrDefault(m => m.Status == Blockstatus.帅 && m.Side == Gameside.黑);
                    //找到红帅的位置
                    var hongshuaiNow = Blocks.FirstOrDefault(m => m.Status == Blockstatus.帅 && m.Side == Gameside.红);
                    //先定义一个将帅之间棋子的个数
                    var countBetweenKing = 2;
                    //如果二者在一条直线上则判断二者之间有没有棋子
                    if (heijiangNow.Point.Y == hongshuaiNow.Point.Y)
                    {
                        countBetweenKing = Blocks.Count(m => m.Point.Y == heijiangNow.Point.Y && m.Point.X > heijiangNow.Point.X
                        && m.Point.X < hongshuaiNow.Point.X && m.Status != Blockstatus.空);
                    }
                    //判断移动是否有效
                    switch (MouseBlock.Status)
                    {
                        //帅、将的走法
                        case Blockstatus.帅:
                            //需要判断是否和黑将打照面
                            if (MouseBlock.Side == Gameside.红)
                            {
                                //红帅
                                //如果黑将的位置没有和红帅的目标block在一列上
                                if (pointDestination.Y != heijiangNow.Point.Y)
                                {
                                    //红帅不能走出红方九宫格
                                    if ((pointDestination.X < 10 && pointDestination.X > 7) && (pointDestination.Y > 2 && pointDestination.Y < 6))
                                    {
                                        //红帅只能上下左右移动一格，如果不是，则不合法
                                        if (!((_X == 0 && _Y == -1) || (_X == 0 && _Y == 1) || (_X == -1 && _Y == 0) || (_X == 1 && _Y == 0)))
                                        {
                                            Flag = false;
                                            break;
                                        }
                                    }
                                    //走出红方九宫格则移动不合法
                                    else
                                    {
                                        Flag = false;
                                        break;
                                    }
                                }
                                //如果黑将的位置和红帅的目标block在一列上
                                else if (heijiangNow.Point.Y == pointDestination.Y)
                                {
                                    //看是否二者之间有棋子
                                    var blackcol = Blocks.Count(m => m.Point.Y == pointDestination.Y &&
                                      (m.Point.X - pointDestination.X) * (m.Point.X - heijiangNow.Point.X) < 0 && m.Status != Blockstatus.空);
                                    if (blackcol == 0)
                                    {
                                        //没有棋子则移动不合法（不能打照面）
                                        Flag = false;
                                        break;
                                    }
                                }

                            }
                            else
                            {
                                //黑将
                                //如果黑将的目标block和红帅没有在一列上
                                if (pointDestination.Y != pointDestination.Y)
                                {
                                    //黑将不能走出黑方九宫格
                                    if ((pointDestination.X < 3 && pointDestination.X > -1) && (pointDestination.Y > 2 && pointDestination.Y < 6))
                                    {
                                        //黑将在九宫格里移动只能上下左右移动一格
                                        if (!((_X == 0 && _Y == -1) || (_X == 0 && _Y == 1) || (_X == -1 && _Y == 0) || (_X == 1 && _Y == 0)))
                                        {
                                            Flag = false;
                                            break;
                                        }

                                    }
                                    //走出黑方九宫格则移动不合法
                                    else
                                    {
                                        Flag = false;
                                        break;
                                    }
                                }
                                //如果红帅在黑帅目标block的那一列上
                                else if (hongshuaiNow.Point.Y == pointDestination.Y)
                                {
                                    //找出二者之间有没有棋子
                                    var redcol = Blocks.Count(m => m.Point.Y == pointDestination.Y &&
                                      (m.Point.X - pointDestination.X) * (m.Point.X - hongshuaiNow.Point.X) < 0 && m.Status != Blockstatus.空);
                                    if (redcol == 0)
                                    {
                                        //如果没有棋子则不合法
                                        Flag = false;
                                        break;
                                    }
                                }
                            }
                            break;
                        //士的走法
                        case Blockstatus.士:
                            //走动时需要判断走后是否将帅打照面
                            if (countBetweenKing == 1 && MouseBlock.Point.Y == heijiangNow.Point.Y)
                            {
                                //将帅在同一列并且中间只有一个子，移开后打照面了 
                                Flag = false;
                                break;
                            }
                            else
                            {
                                //没有打照面
                                if (MouseBlock.Side == Gameside.红)
                                {
                                    //红仕
                                    //不能走出红方九宫格
                                    if ((pointDestination.X < 10 && pointDestination.X > 7) && (pointDestination.Y > 2 && pointDestination.Y < 6))
                                    {
                                        //只能在红方九宫格里斜着走，否则不合法
                                        if (!((_X == 1 && _Y == -1) || (_X == 1 && _Y == 1) || (_X == -1 && _Y == 1) || (_X == -1 && _Y == -1)))
                                        {
                                            Flag = false;
                                            break;
                                        }
                                    }
                                    //走出红方九宫格也不合法
                                    else
                                    {
                                        Flag = false;
                                        break;
                                    }

                                }
                                else
                                {
                                    //黑士
                                    //不能走出黑方九宫格
                                    if ((pointDestination.X < 3 && pointDestination.X >= 0) && (pointDestination.Y > 2 && pointDestination.Y < 6))
                                    {
                                        //黑士在黑方九宫格内斜着走，否则不合法
                                        if (!((_X == 1 && _Y == -1) || (_X == 1 && _Y == 1) || (_X == -1 && _Y == -1) || (_X == -1 && _Y == 1)))
                                        {
                                            Flag = false;
                                            break;
                                        }
                                    }
                                    //走出黑方九宫格也不合法
                                    else
                                    {
                                        Flag = false;
                                        break;
                                    }
                                }

                            }
                            break;
                        //象的走法
                        case Blockstatus.象:
                            //走动时需要判断走后是否将帅打照面
                            if (countBetweenKing == 1 && MouseBlock.Point.Y == heijiangNow.Point.Y)
                            {
                                //将帅在同一列并且中间只有一个子，移开后打照面了 
                                Flag = false;
                                break;
                            }
                            else
                            {
                                //没有打照面
                                //找出起始点和目标点二者之间有没有棋子
                                var blockCount = Blocks.Count(m => (m.Point.X - pointSource.X) * (m.Point.X - pointDestination.X) < 0 &&
                                (m.Point.Y - pointSource.Y) * (m.Point.Y - pointDestination.Y) < 0 && m.Status != Blockstatus.空);
                                if (MouseBlock.Side == Gameside.红)
                                {
                                    //红相，只能在红方区域行走，否则不合法
                                    if (!(pointDestination.X < 10 && pointDestination.X > 4))
                                    {
                                        Flag = false;
                                        break;
                                    }
                                    //象走田，其余走法不合法
                                    else if (!(_X == 2 && _Y == -2 || _X == 2 && _Y == 2 || _X == -2 && _Y == -2 || _X == -2 && _Y == 2))
                                    {
                                        Flag = false;
                                        break;
                                    }
                                    else if (blockCount > 0)
                                    {
                                        //有棋子，被塞象眼，移动不合法
                                        Flag = false;
                                        break;
                                    }
                                }
                                else
                                {
                                    //黑象，只能在黑方区域行走，否则不合法
                                    if (!(pointDestination.X <= 4 && pointDestination.X >= 0))
                                    {
                                        Flag = false;
                                        break;
                                    }
                                    //象走田，其余走法不合法
                                    else if (!(_X == 2 && _Y == -2 || _X == 2 && _Y == 2 || _X == -2 && _Y == -2 || _X == -2 && _Y == 2))
                                    {
                                        Flag = false;
                                        break;
                                    }

                                    else if (blockCount > 0)
                                    {
                                        //有棋子，被塞象眼，移动不合法
                                        Flag = false;
                                        break;
                                    }
                                }
                            }
                            break;
                        //马的走法
                        case Blockstatus.马:
                            //走动时需要判断走后是否将帅打照面
                            if (countBetweenKing == 1 && MouseBlock.Point.Y == heijiangNow.Point.Y)
                            {
                                //将帅在同一列并且中间只有一个子，移开后打照面了 
                                Flag = false;
                                break;
                            }
                            else
                            {
                                //没有打照面
                                //马走日，有八面威风，能走八个点，否则非法
                                if (!((_X == 2 && _Y == 1) || (_X == 2 && _Y == -1) || (_X == -2 && _Y == 1) || (_X == -2 && _Y == -1) ||
                                    (_Y == 2 && _X == 1) || (_Y == 2 && _X == -1) || (_Y == -2 && _X == 1) || (_Y == -2 && _X == -1)))
                                {
                                    Flag = false;
                                    break;
                                }
                                //若是走的日，则判断是否被撇马腿，若被撇马腿则移动不合法
                                else
                                {
                                    //马走日可以看成先走两步在走一步的折线
                                    //判断走两步的方向是否有棋子，如果有则非法
                                    //横着走两步，竖着走一步
                                    var blockNextcount1 = Blocks.Count(m => m.Point.Y == pointSource.Y && (m.Point.X - pointSource.X) *
                                    (m.Point.X - pointDestination.X) < 0 && m.Status != Blockstatus.空);
                                    //横着走一步，竖着走两步
                                    var blockNextcount2 = Blocks.Count(m => m.Point.X == pointSource.X && (m.Point.Y - pointSource.Y) *
                                    (m.Point.Y - pointDestination.Y) < 0 && m.Status != Blockstatus.空);
                                    if (((_X == 2 && _Y == 1) || (_X == 2 && _Y == -1)) && blockNextcount1 > 0)
                                    {
                                        //往下走两步
                                        Flag = false;
                                        break;
                                    }
                                    else if (((_X == -2 && _Y == 1) || (_X == -2 && _Y == -1)) && blockNextcount1 > 0)
                                    {
                                        //往上走两步
                                        Flag = false;
                                        break;
                                    }
                                    else if (((_Y == 2 && _X == 1) || (_Y == 2 && _X == -1)) && blockNextcount2 > 0)
                                    {
                                        //往右走两步
                                        Flag = false;
                                        break;
                                    }
                                    else if (((_Y == -2 && _X == 1) || (_Y == -2 && _X == -1)) && blockNextcount2 > 0)
                                    {
                                        //往左走两步
                                        Flag = false;
                                        break;
                                    }
                                }
                            }
                            break;
                        //车的走法
                        case Blockstatus.车:
                            //走动时需要判断走后是否将帅打照面
                            if (countBetweenKing == 1 && MouseBlock.Point.Y == heijiangNow.Point.Y && _Y != 0)
                            {
                                //将帅在同一列并且中间只有一个子，并且移开的Y坐标不为零，移开后打照面了 
                                Flag = false;
                                break;
                            }
                            else
                            {
                                //走动后没有打照面
                                //如果落点不和原来位置同行或同列则非法
                                if (!((_X != 0 && _Y == 0) || (_Y != 0 && _X == 0)))
                                {
                                    Flag = false;
                                    break;
                                }
                                else
                                {
                                    //平车
                                    if (_X == 0)
                                    {
                                        //找出起始点和目标点之间棋子个数
                                        var count = Blocks.Count(m => m.Point.X == pointDestination.X && (m.Point.Y - pointSource.Y) *
                                        (m.Point.Y - pointDestination.Y) < 0 && m.Status != Blockstatus.空);
                                        if (count > 0)
                                        {
                                            //如果起始和终止位置之间有棋子则不合法
                                            Flag = false;
                                            break;
                                        }
                                    }
                                    //进退车
                                    else
                                    {
                                        //找出起始点和目标点之间棋子个数
                                        var count = Blocks.Count(m => m.Point.Y == pointDestination.Y && (m.Point.X - pointSource.X) *
                                        (m.Point.X - pointDestination.X) < 0 && m.Status != Blockstatus.空);
                                        if (count > 0)
                                        {
                                            //如果起始和终止位置之间有棋子则不合法 
                                            Flag = false;
                                            break;
                                        }
                                    }
                                }
                            }
                            break;
                        //炮的走法
                        case Blockstatus.炮:
                            //走动时需要判断走后是否将帅打照面
                            if (countBetweenKing == 1 && MouseBlock.Point.Y == heijiangNow.Point.Y && _Y != 0)
                            {
                                //将帅在同一列并且中间只有一个子，并且移开的Y坐标不为零，移开后打照面了 
                                Flag = false;
                                break;
                            }
                            else
                            {
                                //如果落点不和原来位置同行或同列则非法
                                if (!((_X != 0 && _Y == 0) || (_Y != 0 && _X == 0)))
                                {
                                    Flag = false;
                                    break;
                                }
                                else
                                {
                                    //走动后没有打照面
                                    //平炮
                                    if (_X == 0)
                                    {

                                        //不吃子
                                        if (BlockSelect.Status == Blockstatus.空)
                                        {
                                            if (_Y < 0)
                                            {
                                                //找出起始点和终止点之间的棋子个数
                                                var count = Blocks.Count(m => m.Point.X == pointDestination.X && (m.Point.Y - pointSource.Y) *
                                                (m.Point.Y - pointDestination.Y + 1) < 0 && m.Status != Blockstatus.空);
                                                if (count > 0)
                                                {
                                                    //如果起始和终止之间有棋子且目标block有棋子则不合法
                                                    Flag = false;
                                                    break;
                                                }
                                            }
                                            else
                                            {
                                                //找出起始点和终止点之间的棋子个数
                                                var count = Blocks.Count(m => m.Point.X == pointDestination.X && (m.Point.Y - pointSource.Y) *
                                                (m.Point.Y - pointDestination.Y - 1) < 0 && m.Status != Blockstatus.空);
                                                if (count > 0)
                                                {
                                                    //如果起始和终止之间有棋子且目标block有棋子则不合法
                                                    Flag = false;
                                                    break;
                                                }
                                            }
                                        }
                                        //吃子
                                        else
                                        {
                                            //找出起始点和终止点之间的棋子个数
                                            var count = Blocks.Count(m => m.Point.X == pointDestination.X && (m.Point.Y - pointSource.Y) *
                                            (m.Point.Y - pointDestination.Y) < 0 && m.Status != Blockstatus.空);
                                            if (count == 0 || count > 1)
                                            {
                                                //如果起始和终止之间没有棋子或者有多个棋子且目标block有棋子则不合法
                                                Flag = false;
                                                break;
                                            }
                                        }


                                    }
                                    //进退炮
                                    else
                                    {
                                        //不吃子
                                        if (BlockSelect.Status == Blockstatus.空)
                                        {
                                            if (_X < 0)
                                            {
                                                //找出起始点和终止点之间的棋子个数
                                                var count = Blocks.Count(m => m.Point.Y == pointDestination.Y && (m.Point.X - pointSource.X) *
                                                (m.Point.X - pointDestination.X + 1) < 0 && m.Status != Blockstatus.空);
                                                if (count > 0)
                                                {
                                                    //如果起始和终止之间有棋子且目标block有棋子则不合法 
                                                    Flag = false;
                                                    break;
                                                }
                                            }
                                            else
                                            {
                                                //找出起始点和终止点之间的棋子个数
                                                var count = Blocks.Count(m => m.Point.Y == pointDestination.Y && (m.Point.X - pointSource.X) *
                                                (m.Point.X - pointDestination.X - 1) < 0 && m.Status != Blockstatus.空);
                                                if (count > 0)
                                                {
                                                    //如果起始和终止之间有棋子且目标block有棋子则不合法 
                                                    Flag = false;
                                                    break;
                                                }
                                            }
                                        }
                                        //吃子
                                        if (BlockSelect.Status != Blockstatus.空)
                                        {
                                            //找出起始点和目标点之间的棋子个数
                                            var count = Blocks.Count(m => m.Point.Y == pointDestination.Y && (m.Point.X - pointSource.X) *
                                            (m.Point.X - pointDestination.X) < 0 && m.Status != Blockstatus.空);
                                            if (count == 0 || count > 1)
                                            {
                                                //如果起始和终止之间没有棋子或者有多个棋子且目标block有棋子则不合法
                                                Flag = false;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                            break;
                        //兵的走法
                        case Blockstatus.兵:
                            //走动时需要判断走后是否将帅打照面
                            if (countBetweenKing == 1 && MouseBlock.Point.Y == heijiangNow.Point.Y && _Y != 0)
                            {
                                //将帅在同一列并且中间只有一个子，并且移开的Y坐标不为零，移开后打照面了 
                                Flag = false;
                                break;
                            }
                            else
                            {
                                //走动后没有打照面
                                //红兵
                                if (MouseBlock.Side == Gameside.红)
                                {
                                    if (pointSource.X > 4)
                                    {
                                        //红兵未过河只能向上
                                        if (_Y != 0 || _X != -1)
                                        {
                                            Flag = false;
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        //过河以后可以横着走，不能后退
                                        if (!((_X == 0 && _Y == -1) || (_X == 0 && _Y == 1) || (_X == -1 && _Y == 0)))
                                        {
                                            Flag = false;
                                            break;
                                        }
                                    }
                                }
                                //黑兵
                                else
                                {
                                    //黑兵未过河只能往下走一步
                                    if (pointSource.X < 5)
                                    {
                                        if (_Y != 0 || _X != 1)
                                        {
                                            Flag = false;
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        //过河以后可以横着走，不能后退
                                        if (!((_X == 0 && _Y == -1) || (_X == 0 && _Y == 1) || (_X == 1 && _Y == 0)))
                                        {
                                            Flag = false;
                                            break;
                                        }
                                    }
                                }
                            }
                            break;
                        case Blockstatus.空:
                            break;
                        default:
                            break;
                    }
                }
                else
                {
                    //其余的移动都不合法
                    Flag = false;
                }
                if (Flag)
                {
                    //移动成功后步时复原
                    NextTime = System.DateTime.Now.AddSeconds(90);
                    //播放落子的音乐
                    SoundPlayer player = new SoundPlayer(Properties.Resources.落下棋子);
                    player.Play();
                    //如果移动合法，则当前block的属性和方向与鼠标移动的block的一致
                    BlockSelect.Side = MouseBlock.Side;
                    BlockSelect.Status = MouseBlock.Status;
                    //改变当前block的UpSelect属性，让它产生一个绿色的边框
                    if (BlockNow.Status != Blockstatus.空)
                    {
                        BlockSelect.UpSelect = true;
                    }
                    MouseBlock.Status = Blockstatus.空;
                    //记录棋谱
                    //先判断是否出现同一列出现两个车、马、炮、兵的情况，棋谱记录会有“前 / 后X”的情况，找出数字
                    var blockSameCount = Blocks.Count(m => m.Point.Y == pointSource.Y && m.Side == BlockSelect.Side && m.Status == BlockSelect.Status &&
                    (m.Status == Blockstatus.兵 || m.Status == Blockstatus.炮 || m.Status == Blockstatus.车 || m.Status == Blockstatus.马));
                    if ((blockSameCount == 1 && _Y != 0) || (blockSameCount == 2 && _Y == 0))
                    {
                        //走之前有两个车、马、炮、兵同列的情况
                        //找到那个相同棋子的坐标位置
                        var blockSame = Blocks.FirstOrDefault(m => m.Point.Y == pointSource.Y && m.Side == BlockSelect.Side && m.Status == BlockSelect.Status && m.Point.X != BlockSelect.Point.X &&
                      (m.Status == Blockstatus.兵 || m.Status == Blockstatus.炮 || m.Status == Blockstatus.车 || m.Status == Blockstatus.马));
                        //定义一个__X来确定相同棋子的位置
                        int __X = blockSame.Point.X - BlockNow.Point.X;
                        if (__X > 0)
                        {
                            //相同棋子在当前棋子的下方
                            if (_X == 0)
                            {
                                //车、炮、兵横着走
                                if (BlockSelect.Side == Gameside.红)
                                {
                                    //被选中的红色棋子在前
                                    MessageStr = ThisSide.ToString() + "：" + "前" + BlockSelect.Status.ToString() + "平" + (9 - BlockSelect.Point.Y).ToString();
                                }
                                else
                                {
                                    //被选中的黑色棋子在后
                                    MessageStr = ThisSide.ToString() + "：" + "后" + BlockSelect.Status.ToString() + "平" + (BlockSelect.Point.Y + 1).ToString();
                                }
                            }
                            else if (_Y == 0)
                            {
                                //车、炮、兵竖着走
                                if (BlockNow.Side == Gameside.红)
                                {
                                    //被选中的红色棋子在前
                                    if (_X > 0)
                                    {
                                        //往后退
                                        MessageStr = ThisSide.ToString() + "：" + "前" + BlockSelect.Status.ToString() + "退" + _X.ToString();
                                    }
                                    else
                                    {
                                        //往前走
                                        MessageStr = ThisSide.ToString() + "：" + "前" + BlockSelect.Status.ToString() + "进" + (_X * -1).ToString();
                                    }
                                }
                                else
                                {
                                    //被选中的黑色棋子在后
                                    if (_X > 0)
                                    {
                                        //往前走
                                        MessageStr = ThisSide.ToString() + "：" + "后" + BlockSelect.Status.ToString() + "进" + _X.ToString();
                                    }
                                    else
                                    {
                                        //往后退
                                        MessageStr = ThisSide.ToString() + "：" + "后" + BlockSelect.Status.ToString() + "退" + (_X * -1).ToString();
                                    }
                                }
                            }
                            else
                            {
                                //马斜着走
                                if (BlockNow.Side == Gameside.红)
                                {
                                    //被选中的棋子在前
                                    if (_X > 0)
                                    {
                                        //向后退
                                        MessageStr = ThisSide.ToString() + "：" + "前" + "马" + "退" + (9 - BlockSelect.Point.Y).ToString();
                                    }
                                    else
                                    {
                                        //往前走
                                        MessageStr = ThisSide.ToString() + "：" + "前" + "马" + "进" + (9 - BlockSelect.Point.Y).ToString();
                                    }
                                }
                                else
                                {
                                    //被选中的棋子在后
                                    if (_X > 0)
                                    {
                                        //往前走
                                        MessageStr = ThisSide.ToString() + "：" + "后" + "马" + "进" + (BlockSelect.Point.Y + 1).ToString();
                                    }
                                    else
                                    {
                                        //向后退
                                        MessageStr = ThisSide.ToString() + "：" + "后" + "马" + "退" + (BlockSelect.Point.Y + 1).ToString();
                                    }
                                }
                            }

                        }
                        else
                        {
                            //相同棋子在当前棋子的上方
                            if (_X == 0)
                            {
                                //车马炮横着走
                                if (BlockSelect.Side == Gameside.红)
                                {
                                    //红方，被选中的棋子在后
                                    MessageStr = ThisSide.ToString() + "：" + "后" + BlockSelect.Status.ToString() + "平" + (9 - BlockSelect.Point.Y).ToString();
                                }
                                else
                                {
                                    //黑方，被选中的棋子在前
                                    MessageStr = ThisSide.ToString() + "：" + "前" + BlockSelect.Status.ToString() + "平" + (BlockSelect.Point.Y + 1).ToString();
                                }
                            }
                            else if (_Y == 0)
                            {
                                //车马炮竖着走
                                if (BlockNow.Side == Gameside.红)
                                {
                                    //红方，被选中的棋子在后
                                    if (_X > 0)
                                    {
                                        //往前走
                                        MessageStr = ThisSide.ToString() + "：" + "后" + BlockSelect.Status.ToString() + "退" + _X.ToString();
                                    }
                                    else
                                    {
                                        //往后走
                                        MessageStr = ThisSide.ToString() + "：" + "后" + BlockSelect.Status.ToString() + "进" + (_X * -1).ToString();
                                    }
                                }

                                else
                                {
                                    //黑方，被选中棋子在前
                                    if (_X > 0)
                                    {
                                        //往前走
                                        MessageStr = ThisSide.ToString() + "：" + "前" + BlockSelect.Status.ToString() + "进" + _X.ToString();
                                    }
                                    else
                                    {
                                        //往后走
                                        MessageStr = ThisSide.ToString() + "：" + "前" + BlockSelect.Status.ToString() + "退" + (_X * -1).ToString();
                                    }
                                }
                            }
                            else
                            {
                                //马斜着走
                                if (BlockNow.Side == Gameside.红)
                                {
                                    //红马,被选中棋子在后
                                    if (_X > 0)
                                    {
                                        //往后走
                                        MessageStr = ThisSide.ToString() + "：" + "后" + "马" + "退" + (9 - BlockSelect.Point.Y).ToString();
                                    }
                                    else
                                    {
                                        //往前走
                                        MessageStr = ThisSide.ToString() + "：" + "后" + "马" + "进" + (9 - BlockSelect.Point.Y).ToString();
                                    }
                                }
                                if (BlockNow.Side == Gameside.黑)
                                {
                                    //黑马
                                    if (_X > 0)
                                    {
                                        //往前走
                                        MessageStr = ThisSide.ToString() + "：" + "前" + "马" + "进" + (1 + BlockSelect.Point.Y).ToString();
                                    }
                                    else
                                    {
                                        //往后走
                                        MessageStr = ThisSide.ToString() + "：" + "前" + "马" + "退" + (1 + BlockSelect.Point.Y).ToString();
                                    }
                                }
                            }
                        }

                    }
                    else
                    {
                        //没有出现相同棋子在一列的情况
                        if (BlockSelect.Status == Blockstatus.兵 || BlockSelect.Status == Blockstatus.车 ||
               BlockSelect.Status == Blockstatus.炮 || BlockSelect.Status == Blockstatus.帅)
                        {
                            //车炮兵帅的记录方法
                            if (_X == 0)
                            {
                                //横着走
                                if (BlockSelect.Side == Gameside.红)
                                {
                                    //红
                                    MessageStr = ThisSide.ToString() + "：" + BlockSelect.Status.ToString() + (9 - MouseBlock.Point.Y).ToString() + "平" + (9 - BlockSelect.Point.Y).ToString();
                                }
                                else
                                {
                                    //黑棋，注意“将”“卒”的字和红方有区别
                                    if (BlockSelect.Status == Blockstatus.帅)
                                    {
                                        MessageStr = ThisSide.ToString() + "：" + "将" + (MouseBlock.Point.Y + 1).ToString() + "平" + (BlockSelect.Point.Y + 1).ToString();
                                    }
                                    else if (BlockSelect.Status == Blockstatus.兵)
                                    {
                                        MessageStr = ThisSide.ToString() + "：" + "卒" + (MouseBlock.Point.Y + 1).ToString() + "平" + (BlockSelect.Point.Y + 1).ToString();
                                    }
                                    else
                                    {
                                        MessageStr = ThisSide.ToString() + "：" + BlockSelect.Status.ToString() + (MouseBlock.Point.Y + 1).ToString() + "平" + (BlockSelect.Point.Y + 1).ToString();
                                    }
                                }
                            }
                            else
                            {
                                //竖着走
                                if (_X > 0)
                                {
                                    //向下走
                                    if (BlockSelect.Side == Gameside.红)
                                    {
                                        //红方，往后退
                                        MessageStr = ThisSide.ToString() + "：" + BlockSelect.Status.ToString() + (9 - MouseBlock.Point.Y).ToString() + "退" + _X.ToString();
                                    }
                                    else
                                    {
                                        //黑棋，注意“将”“卒”的字和红方有区别，往前进
                                        if (BlockSelect.Status == Blockstatus.帅)
                                        {
                                            MessageStr = ThisSide.ToString() + "：" + "将" + (MouseBlock.Point.Y + 1).ToString() + "进" + _X.ToString();
                                        }
                                        else if (BlockSelect.Status == Blockstatus.兵)
                                        {
                                            MessageStr = ThisSide.ToString() + "：" + "卒" + (MouseBlock.Point.Y + 1).ToString() + "进" + _X.ToString();
                                        }
                                        else
                                        {
                                            MessageStr = ThisSide.ToString() + "：" + BlockSelect.Status.ToString() + (MouseBlock.Point.Y + 1).ToString() + "进" + _X.ToString();
                                        }

                                    }
                                }
                                else
                                {
                                    //向上走
                                    if (BlockSelect.Side == Gameside.红)
                                    {
                                        //红方，往前走
                                        MessageStr = ThisSide.ToString() + "：" + BlockSelect.Status.ToString() + (9 - MouseBlock.Point.Y).ToString() + "进" + (_X * -1).ToString();
                                    }
                                    else
                                    {
                                        //黑棋，注意“将”“卒”的字和红方有区别，往后退
                                        if (BlockSelect.Status == Blockstatus.帅)
                                        {
                                            MessageStr = ThisSide.ToString() + "：" + "将" + (MouseBlock.Point.Y + 1).ToString() + "退" + (_X * -1).ToString();
                                        }
                                        else if (BlockSelect.Status == Blockstatus.兵)
                                        {
                                            MessageStr = ThisSide.ToString() + "：" + "卒" + (MouseBlock.Point.Y + 1).ToString() + "退" + (_X * -1).ToString();
                                        }
                                        else
                                        {
                                            MessageStr = ThisSide.ToString() + "：" + BlockSelect.Status.ToString() + (MouseBlock.Point.Y + 1).ToString() + "退" + (_X * -1).ToString();
                                        }

                                    }
                                }
                            }
                        }
                        else if (BlockSelect.Status != Blockstatus.空)
                        {
                            //马象士的走法
                            if (_X > 0)
                            {
                                //向下斜着走
                                if (BlockSelect.Side == Gameside.红)
                                {
                                    //红方，注意相士字的区别，往后退
                                    if (BlockSelect.Status == Blockstatus.象)
                                    {
                                        MessageStr = ThisSide.ToString() + "：" + "相" + (9 - MouseBlock.Point.Y).ToString() + "退" + (9 - BlockSelect.Point.Y).ToString();
                                    }
                                    else if (BlockSelect.Status == Blockstatus.士)
                                    {
                                        MessageStr = ThisSide.ToString() + "：" + "仕" + (9 - MouseBlock.Point.Y).ToString() + "退" + (9 - BlockSelect.Point.Y).ToString();
                                    }
                                    else
                                    {
                                        MessageStr = ThisSide.ToString() + "：" + BlockSelect.Status.ToString() + (9 - MouseBlock.Point.Y).ToString() + "退" + (9 - BlockSelect.Point.Y).ToString();
                                    }
                                }
                                else
                                {
                                    //黑方，往前走
                                    MessageStr = ThisSide.ToString() + "：" + BlockSelect.Status.ToString() + (MouseBlock.Point.Y + 1).ToString() + "进" + (BlockSelect.Point.Y + 1).ToString();
                                }
                            }
                            else
                            {
                                //向上斜着走
                                if (BlockSelect.Side == Gameside.红)
                                {
                                    //红方，注意相士字的区别，往后退
                                    if (BlockSelect.Status == Blockstatus.象)
                                    {
                                        MessageStr = ThisSide.ToString() + "：" + "相" + (9 - MouseBlock.Point.Y).ToString() + "进" + (9 - BlockSelect.Point.Y).ToString();
                                    }
                                    else if (BlockSelect.Status == Blockstatus.士)
                                    {
                                        MessageStr = ThisSide.ToString() + "：" + "仕" + (9 - MouseBlock.Point.Y).ToString() + "进" + (9 - BlockSelect.Point.Y).ToString();
                                    }
                                    else
                                    {
                                        MessageStr = ThisSide.ToString() + "：" + BlockSelect.Status.ToString() + (9 - MouseBlock.Point.Y).ToString() + "进" + (9 - BlockSelect.Point.Y).ToString();
                                    }
                                }
                                else
                                {
                                    //黑方，往前进
                                    MessageStr = ThisSide.ToString() + "：" + BlockSelect.Status.ToString() + (MouseBlock.Point.Y + 1).ToString() + "退" + (9 - BlockSelect.Point.Y).ToString();
                                }
                            }
                        }
                        else
                        {
                            MessageStr = "点击错误！！";
                        }
                    }

                    // 改变当前正在进行游戏的一方
                    ThisSide = MouseBlock.Side == Gameside.红 ? Gameside.黑 : Gameside.红;
                }
            }
            //通知frmmain游戏已经发生改变
            gameChanged?.Invoke();
        }
        /// <summary>
        /// 判断游戏结束
        /// </summary>
        /// <returns>返回值，为0则场上没有黑将，为1则场上没有红帅，为2则场上二者均有，游戏未结束</returns>
        public int IsGameOver()
        {
            //判断场上红黑方老王的个数
            var blackKingNow = Blocks.Count(m => m.Status == Blockstatus.帅 && m.Side == Gameside.黑);
            var redKingNow = Blocks.Count(m => m.Status == Blockstatus.帅 && m.Side == Gameside.红);
            if (blackKingNow != 1)
            {
                //黑将没了
                return 0;
            }
            else if (redKingNow != 1)
            {
                //红帅没了
                return 1;
            }
            else
            {
                //二者都在，啥事儿没有
                return 2;
            }
        }
    }
}